/**
 * 下载工具函数
 * 提供更好的下载体验和错误处理
 */

/**
 * 下载文件
 * @param {string} url - 文件 URL
 * @param {string} filename - 文件名
 * @param {Function} onProgress - 进度回调函数（可选）
 * @param {Function} onSuccess - 成功回调函数（可选）
 * @param {Function} onError - 错误回调函数（可选）
 */
export async function downloadFile(url, filename, { onProgress, onSuccess, onError } = {}) {
    try {
        // 检查是否支持 fetch
        if (!window.fetch) {
            throw new Error('您的浏览器不支持文件下载功能')
        }

        // 开始下载提示
        if (onProgress) {
            onProgress({ status: 'starting', progress: 0 })
        }

        // 发起请求
        const response = await fetch(url)

        if (!response.ok) {
            throw new Error(`下载失败: ${response.status} ${response.statusText}`)
        }

        // 获取文件大小
        const contentLength = response.headers.get('content-length')
        const total = contentLength ? parseInt(contentLength, 10) : 0

        // 创建 ReadableStream 读取器
        const reader = response.body?.getReader()
        if (!reader) {
            // 如果不支持流式下载，回退到简单下载
            return simpleDownload(url, filename, { onSuccess, onError })
        }

        // 读取数据
        const chunks = []
        let received = 0

        while (true) {
            const { done, value } = await reader.read()

            if (done) break

            chunks.push(value)
            received += value.length

            // 更新进度
            if (onProgress && total > 0) {
                const progress = Math.round((received / total) * 100)
                onProgress({ status: 'downloading', progress, received, total })
            }
        }

        // 创建 Blob
        const blob = new Blob(chunks)

        // 创建下载链接
        const downloadUrl = window.URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = downloadUrl
        link.download = filename
        link.style.display = 'none'

        // 触发下载
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)

        // 清理 URL
        window.URL.revokeObjectURL(downloadUrl)

        // 成功回调
        if (onSuccess) {
            onSuccess({ filename, size: received })
        }

        return { success: true, size: received }

    } catch (error) {
        console.error('下载失败:', error)

        // 错误回调
        if (onError) {
            onError(error)
        }

        // 尝试简单下载作为备选方案
        return simpleDownload(url, filename, { onSuccess, onError })
    }
}

/**
 * 简单下载（备选方案）
 * @param {string} url - 文件 URL
 * @param {string} filename - 文件名
 * @param {Object} callbacks - 回调函数
 */
function simpleDownload(url, filename, { onSuccess, onError } = {}) {
    try {
        const link = document.createElement('a')
        link.href = url
        link.download = filename
        link.target = '_blank'
        link.style.display = 'none'

        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)

        // 简单下载无法获取确切的文件大小
        if (onSuccess) {
            onSuccess({ filename, size: 0 })
        }

        return { success: true, size: 0 }

    } catch (error) {
        console.error('简单下载也失败:', error)

        if (onError) {
            onError(error)
        }

        return { success: false, error: error.message }
    }
}

/**
 * 格式化文件大小
 * @param {number} bytes - 字节数
 * @returns {string} 格式化后的大小
 */
export function formatFileSize(bytes) {
    if (bytes === 0) return '0 B'

    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))

    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/**
 * 获取文件扩展名
 * @param {string} filename - 文件名或 URL
 * @returns {string} 扩展名
 */
export function getFileExtension(filename) {
    // 如果是 URL，先提取文件名部分
    const name = filename.split('/').pop() || filename
    return name.split('.').pop()?.toLowerCase() || ''
}

/**
 * 从 URL 中提取原始文件名
 * @param {string} url - 文件 URL
 * @returns {string} 文件名
 */
export function getOriginalFilename(url) {
    // 移除查询参数和锚点
    const cleanUrl = url.split('?')[0].split('#')[0]
    // 提取文件名
    return cleanUrl.split('/').pop() || 'download'
}

/**
 * 验证文件名
 * @param {string} filename - 文件名
 * @returns {string} 安全的文件名
 */
export function sanitizeFilename(filename) {
    // 移除或替换不安全的字符
    return filename
        .replace(/[<>:"/\\|?*]/g, '_')
        .replace(/\s+/g, '_')
        .substring(0, 255) // 限制长度
}

/**
 * 生成下载文件名
 * @param {string} title - 产品标题
 * @param {string} url - 文件 URL
 * @returns {string} 完整的下载文件名
 */
export function generateDownloadFilename(title, url) {
    // 从 URL 中获取原始文件扩展名
    const extension = getFileExtension(url)

    // 清理标题作为文件名
    const cleanTitle = sanitizeFilename(title || 'download')

    // 如果标题已经包含扩展名，直接返回
    if (cleanTitle.toLowerCase().endsWith(`.${extension}`)) {
        return cleanTitle
    }

    // 否则添加扩展名
    return extension ? `${cleanTitle}.${extension}` : cleanTitle
}